import React from 'react';
import { Button, Table, Modal, message, Progress } from 'antd';

import Search from 'antd/lib/input/Search';
import { ColumnsType } from 'antd/lib/table';

import { checkPermission } from 'permission/Index';
import { NumGroupInfo } from '../../../schema/NumGroup';
import { getNumGroupList, deleteNumGroup } from '../../../servers/servers';
import { clearNull, deleteRowChangePageNum, getTableIndex } from '../../../../utils/tools';
import { NumGroupPop } from './component/NumGroupPop';
import { NumGroupCheckDetail } from './component/NumGroupCheckDetail';
import { NumGroupImportPop } from './component/NumGroupImportPop';
import { NumGroupUploadRecord } from './component/NumGroupUploadRecord';

import './style.scss';

/**
 * 号码组管理props
 */
interface IProps {}
/**
 * 号码组管理state
 */
export interface IState {
  // 号码组名称
  callGroupName: string;
  // 新增号码组抽屉控件显隐
  operationVisible: boolean;
  // 展示在table的数据
  tableData: NumGroupInfo[];
  // 详情对话框是否显示
  detailVisible: boolean;
  // 导入记录弹窗显示
  uploadRecordVisible: boolean;
  // 当前选中所要查看详情的数据
  currentId?: number;
  // 分页相关数据
  pageInfo: {
    pageTotal: number;
    pageNum: number;
    pageSize: number;
  };
  tableLoading: boolean;
}

/**
 * 号码组管理页
 */
class NumGroup extends React.Component<IProps, IState> {
  /**
   * table列头
   * 因为table列头相对固定，不需要响应式地修改视图，所以记录在类的私有号码组中而不是react state中，轻量的state利于提升性能
   */
  private columns: ColumnsType<NumGroupInfo>;

  //子组件 号码组操作 的引用
  private operationRef: React.RefObject<NumGroupPop> | undefined;
  //子组件 号码组导入操作 的引用
  private importRef: React.RefObject<NumGroupImportPop> | undefined;

  private timer: any;

  constructor(props: IProps) {
    super(props);
    // 初始数据
    this.state = {
      callGroupName: '',
      detailVisible: false,
      operationVisible: false,
      uploadRecordVisible: false,
      currentId: undefined,
      tableData: [],
      pageInfo: {
        pageTotal: 0,
        pageNum: 1,
        pageSize: 10,
      },
      tableLoading: false,
    };

    this.columns = [
      {
        title: '序号',
        width: 80,
        dataIndex: 'index',
        key: 'index',
        render: (text, record, index) =>
          getTableIndex(index, this.state.pageInfo.pageSize, this.state.pageInfo.pageNum),
      },
      {
        title: '号码组名称',
        dataIndex: 'callGroupName',
        key: 'callGroupName',
      },
      {
        title: '项目',
        dataIndex: 'projectName',
        key: 'projectName',
        width: 200,
      },
      {
        title: '描述',
        dataIndex: 'callGroupDesc',
        key: 'callGroupDesc',
      },
      {
        title: '号码数',
        dataIndex: 'callGroupNumber',
        key: 'callGroupNumber',
        width: 150,
      },
      {
        title: '更新时间',
        dataIndex: 'callGroupEditTime',
        key: 'callGroupEditTime',
        width: 250,
      },
      {
        title: '操作',
        dataIndex: 'operation',
        key: 'operation',
        width: 300,
        render: (text, record, index) => {
          return this.renderOperation(text, record, index);
        },
      },
    ];
    this.operationRef = React.createRef();
    this.importRef = React.createRef();
    this.timer = null;
  }

  public componentDidMount() {
    this.fetchList();
  }

  public componentWillUnmount() {
    console.log('==============页面卸载 leave');
    this.clearTimer();
  }

  /**
   * 渲染操作按钮
   */
  private renderOperation(text: any, record: NumGroupInfo, index: number): JSX.Element {
    const { uploadStatus = 0 } = record;
    if (uploadStatus) {
      return (
        <div className="progress-wrap">
          <div className="tip">导入中</div>
          <Progress
            strokeColor={{
              '0%': '#1f97ff',
              '60%': '#68f2fd',
              '100%': '#1f97ff',
            }}
            percent={99.9}
            showInfo={false}
          />
        </div>
      );
    }
    return (
      <>
        <Button
          type="link"
          onClick={() => {
            this.checkDetail(record);
          }}
        >
          详情
        </Button>
        {checkPermission('/client/numGroup/upload') && (
          <Button
            type="link"
            onClick={() => {
              this.upload(record);
            }}
          >
            上传
          </Button>
        )}
        {checkPermission('/client/numGroup/uploadRecord') && (
          <Button
            type="link"
            onClick={() => {
              this.openUploadRecord(record);
            }}
          >
            导入记录
          </Button>
        )}
        {checkPermission('/client/numGroup/delete') && (
          <Button
            type="link"
            onClick={() => {
              this.deleteRecord(record);
            }}
          >
            删除
          </Button>
        )}
      </>
    );
  }

  /**
   * 根据号码组名称查询列表
   */
  private searchNumGroup(name: string) {
    this.setState(
      {
        callGroupName: name.trim(),
      },
      () => {
        this.jumpPage(1);
      }
    );
  }

  /**
   * 查看号码组详情
   */

  private checkDetail(record: NumGroupInfo) {
    this.setState({
      currentId: record.callGroupId,
      detailVisible: true,
    });
  }

  /**
   * 上传号码组交互
   */
  private upload(record: NumGroupInfo) {
    const modal = this.importRef?.current;
    modal && modal.open();
    modal && modal.setValue(record);
  }

  /**打开导入记录弹窗 */
  private openUploadRecord = (record: NumGroupInfo) => {
    this.setState({
      currentId: record.callGroupId,
      uploadRecordVisible: true,
    });
  };

  /**
   * 删除数据后更新
   */
  private deleteFresh(size: number) {
    const { pageTotal, pageNum, pageSize } = this.state.pageInfo;
    const newPageNum = deleteRowChangePageNum(size, pageTotal, pageNum, pageSize);
    this.setState(
      {
        pageInfo: {
          pageTotal,
          pageSize,
          pageNum: newPageNum,
        },
      },
      () => {
        this.fetchList();
      }
    );
  }
  /**
   * 删除号码组交互
   */
  private deleteRecord(record: NumGroupInfo) {
    Modal.confirm({
      content: '删除号码组后无法恢复，确定删除吗',
      onOk: () => {
        deleteNumGroup(record.callGroupId)
          .then(res => {
            if (res.code === 0) {
              message.success('删除成功');
              this.deleteFresh(1);
            } else {
              message.error(`${res.tips}(错误码: ${res.code})`);
            }
          })
          .catch(error => {
            console.error(`系统异常: ${JSON.stringify(error)}`);
          });
      },
    });
  }
  /**开启定时器 */
  private startTimer() {
    if (this.timer) {
      return;
    }
    // 条件：开启定时1s刷新进度
    this.timer = setInterval(() => {
      this.fetchList(false);
    }, 1000);
    console.log('>>>>>>>>>>>启动定时器', this.timer);
  }

  /**清除定时器 */
  private clearTimer() {
    if (!this.timer) {
      return;
    }
    console.log('=============清除定时器', this.timer);
    clearInterval(this.timer);
    this.timer = null;
  }

  /**
   * 获取列表数据
   */
  private async fetchList(loading = true) {
    loading &&
      this.setState({
        tableLoading: true,
      });
    const { callGroupName, pageInfo } = this.state;
    try {
      const { count = 0, data } = await getNumGroupList(
        clearNull({
          callGroupName: callGroupName,
          pageNo: pageInfo.pageNum,
          pageSize: pageInfo.pageSize,
        })
      );
      pageInfo.pageTotal = count;
      this.setState({
        tableData: data,
        pageInfo: pageInfo,
      });
      this.clearTimer();
      const loadingArr = this.state.tableData.filter(value => value.uploadStatus === 1);
      if (loadingArr.length) {
        console.log('check progress');
        this.startTimer();
      }
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
      this.clearTimer();
    }
    loading &&
      this.setState({
        tableLoading: false,
      });
  }

  /**
   * 跳页方法
   */
  private jumpPage(pageNum: number, pageSize?: number) {
    const newProp = this.state.pageInfo;
    newProp.pageNum = pageNum;
    if (pageSize) {
      newProp.pageSize = pageSize;
    }
    this.setState(
      {
        pageInfo: newProp,
      },
      () => {
        this.fetchList();
      }
    );
  }
  render() {
    const {
      tableData,
      tableLoading,
      pageInfo: { pageNum, pageSize, pageTotal },
      currentId,
      detailVisible,
      uploadRecordVisible,
    } = this.state;

    return (
      <>
        <div className="mgr-header">
          <div className="mgr-header-left">
            <Search
              className="mgr-header-search"
              placeholder="请输入号码组名称"
              enterButton="搜索"
              onSearch={value => this.searchNumGroup(value)}
              allowClear
            />
          </div>
          <div className="mgr-header-right">
            {checkPermission('/client/numGroup/add') && (
              <Button
                type="primary"
                onClick={() => {
                  this.operationRef?.current?.open();
                }}
              >
                新建号码组
              </Button>
            )}
            {checkPermission('/client/numGroup/downloadTemplate') && (
              <Button
                type="primary"
                href="/webapp/callGroup_template.xlsx"
                download="号码组导入模板.xlsx"
              >
                下载模板
              </Button>
            )}
          </div>
        </div>
        <div className="mgr-table num-group-page">
          <Table
            loading={tableLoading}
            scroll={{ x: 'max-content' }}
            columns={this.columns}
            dataSource={tableData}
            rowKey={record => record.callGroupId as number}
            pagination={{
              showSizeChanger: true,
              total: pageTotal,
              showTotal: total => `共 ${total} 条`,
              current: pageNum,
              pageSize: pageSize,
              onChange: (pageNum, pageSize) => {
                this.jumpPage(pageNum, pageSize as number);
              },
            }}
          />
        </div>
        <NumGroupPop ref={this.operationRef} callback={() => this.jumpPage(1)} />
        {detailVisible && (
          <NumGroupCheckDetail
            visible={detailVisible}
            callGroupId={currentId as any}
            onClose={() => {
              this.setState({
                detailVisible: false,
                currentId: undefined,
              });
            }}
          />
        )}
        <NumGroupImportPop ref={this.importRef} callback={() => this.fetchList()} />
        {uploadRecordVisible && (
          <NumGroupUploadRecord
            visible={uploadRecordVisible}
            callGroupId={currentId as any}
            onClose={() => {
              this.setState({
                uploadRecordVisible: false,
                currentId: undefined,
              });
            }}
          />
        )}
      </>
    );
  }
}

export default NumGroup;
